//
//  AppDelegate.m
//  ALittleReminder
//
//  Created by George on 2011-11-01.
//  
// Changes:
// 2011-11-02: set the MainViewControllor for iPhone only (George)
#import <CoreData/CoreData.h>

#import "AppDelegate.h"

#import "MainViewController.h"
#import "AlertManagedObject.h"
#import "DisplayAlertViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[MainViewController alloc] initWithNibName:@"MainViewController_iPhone" bundle:nil];
    //iPhone only for now
    /*if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[MainViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[MainViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
    }*/
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    
    /*
    UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif) {
        //todo view notif locally
    }*/
    
    return YES;
}

// get the view controller that is currently shown to the user
- (UIViewController *) getTopViewController
{
    UIViewController *walk = self.viewController;
    while ([walk presentedViewController]) {
        walk = [walk presentedViewController];
    }
    return walk;
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)localNotif
{
    //UIAlertView *alert = [[UIAlertView alloc] initWithTitle:localNotif.alertBody message:@"" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    //[alert show];
    
    NSURL *alertURL = [NSURL URLWithString:[localNotif.userInfo objectForKey:@"url"]];
    NSManagedObject *alert = [[self managedObjectContext] objectWithID:[[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:alertURL]];
    
    bool viewLaunched = NO;
    while (!viewLaunched) {
        @try {
            DisplayAlertViewController *openView = [[DisplayAlertViewController alloc] initWithAlert:(AlertManagedObject*)alert];
            [[self getTopViewController] presentModalViewController:openView animated:YES];
            viewLaunched = YES;
        }
        @catch (NSException *exception) {
            viewLaunched = NO;
            //an view transition is in progress
            //try again later
            NSLog(@"%@",exception);
            [NSThread sleepForTimeInterval:1];
        }
    }

}

// returns all saved alerts
- (NSArray *) getAllAlerts
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"AlertManagedObject" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    return [[self managedObjectContext] executeFetchRequest:fetchRequest error:nil];
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}


#pragma mark -
#pragma mark Core Data stack
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *)managedObjectContext {
	
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
	
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [NSManagedObjectContext new];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    
    
    return managedObjectContext;
}


/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {
	
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];    
    return managedObjectModel;
}


/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
	
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    
	NSString *storePath = [[AppDelegate applicationDocumentsDirectory] stringByAppendingPathComponent:@"Alerts5.sqlite" ];//Change this name if data model is changed.
	/*
	 Set up the store.
	 */
	// If the expected store doesn't exist, copy the default store.
    /*
     NSFileManager *fileManager = [NSFileManager defaultManager];
	if (![fileManager fileExistsAtPath:storePath]) {
		NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Alerts2" ofType:@"sqlite"];
		if (defaultStorePath) {
			[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
		}
	}*/
	
	NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
	
	NSError *error;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
		/*
		 Replace this implementation with code to handle the error appropriately.
		 
		 abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
		 
		 Typical reasons for an error here include:
		 * The persistent store is not accessible
		 * The schema for the persistent store is incompatible with current managed object model
		 Check the error message to determine what the actual problem was.
		 */
		NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
		abort();
    }    
    
    return persistentStoreCoordinator;
}

#pragma mark - static helper fuctions

/**
 Returns the path to the application's documents directory.
 */
+ (NSString *)applicationDocumentsDirectory {
	return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

+ (AppDelegate *) getInstance{
    return [[UIApplication sharedApplication]delegate];
}

+ (void) saveManagedObjects{
    NSManagedObjectContext *context = [[AppDelegate getInstance] managedObjectContext];
    [context save:nil];
}

+ (void) deleteManagedObject:(AlertManagedObject *)objectToDelete{
    [objectToDelete removeAudioFile];
    NSManagedObjectContext *context = [[AppDelegate getInstance] managedObjectContext];
    [context deleteObject:objectToDelete];
    [context save:nil];
}

@end
